在 Rust 中重新定義物件導向,意味著從僵化的類別層次結構轉向以 資料與行為分離為核心的模型。雖然傳統的系統語言依賴於複雜的物件樹,但 Rust 借由使用 特徵(traits) 和模組來實現物件導向設計目標——封裝與多型,同時優先確保記憶體安全且無執行時開銷。
1. 挑戰層次結構
Rust 明確避免實作繼承,以防止 脆弱基礎類別 問題。相反地,它傾向於組合與 特徵(Traits) 來定義跨不同類型的共享行為。這裡的「物件」是資料(structs)與程序(impl blocks)的組合,且在編譯時期就已驗證。
2. 並行運算與狀態即類型
Rust 主要透過標準函式庫(Send/Sync 特徵)而非語言核心處理並行運算。為了最大化安全性, 狀態即類型演算法 將不同的狀態編碼為不同的類型。狀態轉換會回傳新的實例,將邏輯從執行時的 if 判斷語句移至編譯時期的要求。
main.py
TERMINALbash — 80x24
> Ready. Click "Run" to execute.
>
QUESTION 1
Why does Rust avoid implementation inheritance?
To prevent the 'fragile base class' problem where child classes break due to parent changes.
Because Rust does not support polymorphism.
To ensure all objects are stored on the stack.
Because traits are more memory-intensive than classes.
✅ Correct!
By favoring composition over inheritance, Rust avoids the complexity and tight coupling inherent in deep class hierarchies.❌ Incorrect
Rust supports polymorphism via traits; the avoidance of inheritance is a design choice to ensure maintainability.QUESTION 2
How does Rust define an 'object' according to the Gang of Four philosophy?
A runtime class pointer with a virtual table.
A combination of data (structs) and the procedures that operate on it (impl blocks).
A global variable accessible by any module.
An instance of a template class.
✅ Correct!
Rust uses structs for data and impl blocks for behavior, perfectly mirroring the GoF definition of an object.❌ Incorrect
While dynamic dispatch uses vtables, the core definition of an object in Rust is the pairing of data and methods.QUESTION 3
Where is concurrency logic primarily defined in Rust?
In the core language syntax.
Through mandatory thread models in the compiler.
Primarily through the standard library and external crates.
By the operating system only.
✅ Correct!
Rust's core is lightweight; traits like Send and Sync allow the standard library to handle concurrency safely.❌ Incorrect
Rust's core language doesn't dictate a threading model, allowing for zero-cost abstractions.QUESTION 4
What is the primary benefit of the State-as-Type algorithm?
It reduces the binary size of the application.
It allows for faster runtime execution via dynamic dispatch.
It turns invalid state transitions into compile-time errors.
It automatically generates documentation for states.
✅ Correct!
By making states distinct types, you cannot call a method meant for one state (e.g., 'approve') on a different state (e.g., 'Draft') at the compiler level.❌ Incorrect
The primary goal is safety and correctness, ensuring logic is validated before the program ever runs.QUESTION 5
In the 'encoding states as types' approach, how are state transitions handled?
By modifying a 'status' enum field in a single struct.
By consuming the current state type and returning a new state type.
By using a global state manager.
By casting pointers between different classes.
✅ Correct!
Transformation methods take ownership of 'self', ensuring the old state is invalidated and the new state is correctly initialized.❌ Incorrect
Modifying a field is the traditional OOP way; Rustaceans prefer type transformation for increased safety.Case Study: The Secure Document Workflow
Applying State-as-Type for Compile-Time Safety
You are designing a document system where a 'Draft' can be sent for review, becoming a 'PendingReview' object. You need to implement a 'reject' mechanism that safely returns a 'PendingReview' document back to a 'Draft' state.
Q
Add a reject method that changes the post’s state from PendingReview back to Draft.
Solution:
To implement the
This transition consumes the
To implement the
reject method within the State-as-Type context, we define it on the PendingReview struct to return a Draft: impl PendingReview {
pub fn reject(self) -> Draft {
Draft {
content: self.content,
}
}
}This transition consumes the
PendingReview instance (via self) and returns a new Draft instance, effectively moving the data back to its initial state type while invalidating the old state.Q
How does this implementation prevent a developer from editing a document that is currently in the PendingReview state?
Solution:
In this design, the
In this design, the
add_text method is only implemented for the Draft struct. Once the document is transformed into a PendingReview struct, the add_text method is no longer available on that instance. Any attempt to call it would result in a compile-time error, preventing unauthorized edits during the review process.